/*
 * Utils.java
 *
 * Created on September 10, 2006, 3:35 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package smfbackup;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;
import java.util.StringTokenizer;
import javax.swing.JDialog;
import javax.swing.JFrame;
import org.apache.log4j.Logger;
import smfbackup.conf.Configuration;
import smfbackup.run.Scheduler;

/**
 *
 * @author Iulian
 */
public class Utils {

    private static Logger log = Logger.getLogger(Utils.class);

    /** Creates a new instance of Utils */
    private Utils() {
    }

    public static void exitApplication(Scheduler sch) {

        Configuration.saveConfiguration();

        sch.shutdown();
        System.exit(0);
    }

    public static void centerDialogInParent(JFrame parent, JDialog dialog) {
        int x;
        int y;

        Point topLeft = parent.getLocationOnScreen();
        Dimension parentSize = parent.getSize();

        Dimension mySize = dialog.getSize();

        if (parentSize.width > mySize.width) {
            x = ((parentSize.width - mySize.width) / 2) + topLeft.x;
        } else {
            x = topLeft.x - (mySize.width - parentSize.width) / 2;
        }

        if (parentSize.height > mySize.height) {
            y = ((parentSize.height - mySize.height) / 2) + topLeft.y;
        } else {
            y = topLeft.y - (mySize.height - parentSize.height) / 2;
        }

        if (x < 0) {
            x = 0;
        }
        if (y < 0) {
            y = 0;
        }

        dialog.setLocation(x, y);
    }

    public static void centreFrameOnScreen(JFrame frame) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        Point center = ge.getCenterPoint();
        Rectangle bounds = ge.getMaximumWindowBounds();
        int w = Math.max(bounds.width / 2, Math.min(frame.getWidth(), bounds.width));
        int h = Math.max(bounds.height / 2, Math.min(frame.getHeight(), bounds.height));
        int x = center.x - w / 2, y = center.y - h / 2;
        frame.setBounds(x, y, w, h);
        if (w == bounds.width && h == bounds.height) {
            frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        }
        frame.validate();
    }

    /**
     * Creates a Date from a string HH:mm. Used by JSpinner.
     *
     * @param hm value to be converted
     * @return date representing value
     */
    public static Date createDateFromString(final String hm) {
        try {
            StringTokenizer st = new StringTokenizer(hm, ":");
            GregorianCalendar gc = new GregorianCalendar();

            gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(st.nextToken()));
            gc.set(Calendar.MINUTE, Integer.parseInt(st.nextToken()));

            return gc.getTime();
        } catch (Exception e) {
            log.error(e);
            return new Date();
        }

    }

    /**
     * Returns HH:mm from a date. Used for JSpinner.
     * @param date date to be converted
     * @return HH:mm
     */
    public static String getHourAsString(final Date date) {
        GregorianCalendar c = new GregorianCalendar();
        c.setTime(date);

        return c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE);
    }

    /**
     * Encrypts a given password.
     * @param password
     * @return password encrypted
     */
    public static String encrypt(String password) {
        try {
            byte encr[] = new byte[128];
            Random r = new Random();
            for (int i = 0; i < 128; i++) {
                int c = Math.abs(r.nextInt()) % ('z' - 'a' - 1);
                encr[i] = (byte) ('a' + c);
            }
            for (int i = 0; i < password.length(); i++) {
                encr[i * 4 + 1] = (byte) (password.charAt(i) + 5);
            }
            encr[127] = (byte) (password.length() + 'a');

            return new String(encr);
        } catch (Exception e) {
            log.error(e);
            return password;
        }
    }

    /**
     * Decrypts the given password.
     *
     * @param encpassword password encoded
     * @return decrypted password
     */
    public static String decrypt(final String encpassword) {
        try {
            int len = encpassword.charAt(127) - 'a';
            byte pass[] = new byte[len];

            for (int i = 0; i < len; i++) {
                pass[i] = (byte) (encpassword.charAt(i * 4 + 1) - 5);
            }

            return new String(pass);
        } catch (Exception e) {
            log.error("Unable to decrypt.", e);
            return encpassword;
        }
    }

    /**
     * Converts a given number of bytes to human readable kilobytes.
     * @param value number to convert
     * @return number rendered in kb notation.
     */
    public static String getLongAsKilo(final long value) {
        if (value < 1024) {
            return "" + value;
        } else {
            return (value / 1024) + " kb";
        }
    }

    /**
     * Prints an exception to a String.
     *
     * @param t Exception to be printed.
     * @return String representing the exception's stack trace.
     */
    public static String getStackTraceAsString(final Throwable t) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(baos);

        t.printStackTrace(ps);

        try {
            baos.close();
        } catch (IOException ioe) {
            log.error("Unable to close output stream.", ioe);
        }

        return baos.toString() + "\n";
    }
}
